﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Windows.Forms;

using Alsing.SourceCode;
using Alsing.Windows.Forms.SyntaxBox;
using IronPython.Runtime.Exceptions;
using Microsoft.SharePoint;
using SPCoder.Autorun;
using SPCoder.Config;
using SPCoder.Context;
using SPCoder.Describer;
using SPCoder.HelperWindows;
using SPCoder.Scripting;
using SPCoder.Utils;
using AutoRunScriptsForm=SPCoder.Autorun.AutoRunScriptsForm;
using Alsing.Windows.Forms;
using SPCoder.Utils.Nodes;

namespace SPCoder
{
    /// <summary>
    /// SPCoder main form.
    /// </summary>
    /// <author>Damjan Tomic</author>
    public partial class Main : Form
    {
        #region Fields
        //private readonly SyntaxDefinitionList Languages = new SyntaxDefinitionList();
        private IronPythonContext myContext = new IronPythonContext();
        private SPSite _site;
        //private TreeNode sourceNode;
        private BaseNode dragedBaseNode;
        ObjectDescriber describer = new ObjectDescriber();
        public static readonly IronPythonEngine ironPythonEngine = new IronPythonEngine(); 
        #endregion

        public static Main MainForm;
        public Main()
        {
            InitializeComponent();
            MainForm = this;

            var loader = new SyntaxDefinitionLoader();
            string syntaxXml = SPCoderUtils.LoadStringFromResource("SPCoder.Resources.Python.syn");
            SyntaxDefinition syntax = loader.LoadXML(syntaxXml);
            sourceCodeBox.Document.Parser.Init(syntax);

            myContext.Scope = ironPythonEngine.Scope;

            AddItemToContext(new ContextItem { Data = rtOutput, Name = "rtTxt", Type = rtOutput.GetType().ToString() });
            AddItemToContext(new ContextItem { Data = rtLog, Name = "rtLog", Type = rtLog.GetType().ToString() });
            AddItemToContext(new ContextItem { Data = describer, Name = "describer", Type = describer.GetType().ToString() });
            AddItemToContext(new ContextItem { Data = this, Name = "main", Type = this.GetType().ToString() });
        }

        

        private TracebackDelegate OnTraceback(TraceBackFrame frame, string result, object payload)
        {
            int lineNo = Convert.ToInt32(frame.f_lineno);
            sourceCodeBox.AllowBreakPoints = true;
            //rtOutput.Text += result + " - " + lineNo+" : " + sourceCodeBox.Document.Lines[lineNo - 1] + "\n";
            
            return this.OnTraceback;
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            ExecuteSelection();
        }

        private void ExecuteSelection()
        {
            try
            {
                rtOutput.Clear();
                string text;
                SyntaxBoxControl tempsbc = SourceCodeBox;
                if (tempsbc == null)
                {
                    throw new Exception("Cannot find control box control!");
                }
                string selection = tempsbc.Selection.Text;
                if (string.IsNullOrEmpty(selection))
                {
                    text = tempsbc.Document.Text;
                }
                else
                {
                    text = selection;
                }
                object result = ExecuteScript(text); //ironPythonEngine.Execute(sourceCodeBox.Document.Text); //source.Execute(m_scope);

            }
            catch (Exception ex)
            {
                LogException(ex);
            }
        }

        private void LogException(Exception ex)
        {
            AppendToLog(ex.Message);
            MessageBox.Show("An error has occurred during execution of the script:" + ex.Message);
        }

        private void AppendToLog(string text)
        {
            rtLog.Text += "[" + DateTime.Now.ToShortTimeString() + "]:" + text+"\n";
        }

        protected object ExecuteScript(string script)
        {
            try
            {
                object result = ironPythonEngine.Execute(script);
                return result;
            }
            catch (Exception exc)
            {
                throw exc;
            }
        }

        #region Sharepoint - Tree View Related Methods

        public List<BaseNode> Nodes = new List<BaseNode>();

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            string siteUrl = txtUrl.Text;
            Connect(siteUrl);
        }

        public void Connect(string siteUrl)
        {
            _site = new SPSite(siteUrl);
            BaseNode rootNode = new SPSiteNode(_site);
            rootNode.SPObject = _site;

            doSPWeb(_site.RootWeb, rootNode, rootNode);//, root);
            
            //Now create tree view stuff;
            CreateAllTreeViewNodes(rootNode);
            //Nodes
        }

        private void CreateAllTreeViewNodes(BaseNode rootNode)
        {
            TreeNode root = CreateNode(rootNode.Title, "", rootNode);
            tvSp.Nodes.Add(root);

            CreateTreeViewNode(root, rootNode.Children[0]);
        }

        private void CreateTreeViewNode(TreeNode tvNode, BaseNode node)
        {
            TreeNode myNode = CreateNode(node.Title, node.Icon, node);
            tvNode.Nodes.Add(myNode);
            foreach (BaseNode child in node.Children)
            {
                CreateTreeViewNode(myNode, child);
            }
        }

        private TreeNode CreateNode(string tekst, string imageUrl, Object o)
        {
            string[] s = imageUrl.Split('/');
            if (s.Length > 0)
                imageUrl = s[s.Length - 1];
            TreeNode node = new TreeNode { Text = tekst, Tag = o, ImageKey = imageUrl };
            return node;
        }

        private void doSPWeb(SPWeb web, BaseNode parentNode, BaseNode rootNode)//, TreeNode root)
        {
            //TreeNode node = CreateNode(web.Title, "", web);
            //root.Nodes.Add(node);

            BaseNode myNode = new SPWebNode(web);
            parentNode.Children.Add(myNode);
            myNode.ParentNode = parentNode;
            myNode.RootNode = rootNode;

            foreach (SPWeb childWeb in web.Webs)
            {
                doSPWeb(childWeb, myNode, rootNode);
            }

            foreach (SPList list in web.Lists)
            {
                BaseNode myListNode = new SPListNode(list);
                myNode.Children.Add(myListNode);
                myListNode.ParentNode = myNode;
                myListNode.RootNode = rootNode;
                //TreeNode lnode = CreateNode(list.Title, list.ImageUrl, list);
                //node.Nodes.Add(lnode);
            }
            web.Dispose();
        }

        //private void RefreshSPWeb(BaseNode refreshNode, TreeNode treeNode)
        //{
        //    SPWeb web = refreshNode.SPObject as SPWeb;
        //    if (web != null)
        //    { 
                   
        //    }
        //}

        //private void doRefreshSPWeb(BaseNode refreshNode, TreeNode treeNode)
        //{
        //    //TreeNode node = CreateNode(web.Title, "", web);
        //    //root.Nodes.Add(node);

        //    BaseNode myNode = new SPWebNode(web);
        //    parentNode.Children.Add(myNode);
        //    myNode.ParentNode = parentNode;
        //    myNode.RootNode = rootNode;

        //    foreach (SPWeb childWeb in web.Webs)
        //    {
        //        doSPWeb(childWeb, myNode, rootNode);
        //    }

        //    foreach (SPList list in web.Lists)
        //    {
        //        BaseNode myListNode = new SPListNode(list);
        //        myNode.Children.Add(myListNode);
        //        myListNode.ParentNode = myNode;
        //        myListNode.RootNode = rootNode;
        //        //TreeNode lnode = CreateNode(list.Title, list.ImageUrl, list);
        //        //node.Nodes.Add(lnode);
        //    }
        //    web.Dispose();
        //}

        private void DisposeNode(TreeNode node)
        {
            if (node != null)
            {
                if (node.Tag != null && node.Tag is IDisposable)
                {
                    try
                    {                        
                        ((IDisposable)node.Tag).Dispose();
                    }
                    catch (Exception)
                    {
                        //just skip this
                    }
                }

                foreach (TreeNode treeNode in node.Nodes)
                {
                    DisposeNode(treeNode);
                }
            }
        }

        private void DisposeBaseNodes(BaseNode node)
        {
            if (node != null)
            {
                if (node != null && node.SPObject != null && node.SPObject is IDisposable)
                {
                    try
                    {
                        ((IDisposable)node.SPObject).Dispose();
                    }
                    catch (Exception)
                    {
                        //just skip this
                    }
                }

                foreach (BaseNode treeNode in node.Children)
                {
                    DisposeBaseNodes(treeNode);
                }
            }
        } 
        #endregion

        #region Drag'n'Drop Methods
        private void lbContext_DragDrop(object sender, DragEventArgs e)
        {
            //AddToContext(sourceNode.Tag);
            AddToContext(dragedBaseNode.SPObject);
        }

        private void lbContext_DragEnter(object sender, DragEventArgs e)
        {

            e.Effect = DragDropEffects.Move;
        }


        private void tvSp_ItemDrag(object sender, ItemDragEventArgs e)
        {
            try
            {
                //sourceNode = (TreeNode)e.Item;
                dragedBaseNode = ((TreeNode)e.Item).Tag as BaseNode;
                if (dragedBaseNode != null && dragedBaseNode.SPObject != null)
                {
                    tvSp.DoDragDrop(dragedBaseNode.SPObject, DragDropEffects.Copy | DragDropEffects.Move);    
                }
                
            }
            catch (Exception)
            {
                //this can happen when user tries to drop object to source window
                //just ignore that exception
            }
        } 
        #endregion


        public void AddToContext(object item)
        {
            try
            {                
                ContextItem contextItem = new ContextItem { Data = item, Type = item.GetType().ToString() };
                AddItemToContext(contextItem);
            }
            catch (Exception ex)
            {
                LogException(ex);
            }
        }

        private void AddItemToContext(ContextItem item)
        {
            myContext.AddItem(item);
            lbContext.Items.Add(item);
        }

        private void Main_Load(object sender, EventArgs e)
        {
            ActionDelegate ad = new ActionDelegate(this.ExecuteSelection);
            KeyboardAction ka = new KeyboardAction(Keys.F5, false, false, false, false, ad);

            sourceCodeBox.KeyboardActions.Add(ka);
            ExecuteAutorunScripts();
            ActionDelegate ad1 = new ActionDelegate(this.ShowAutoList);
            KeyboardAction ka1 = new KeyboardAction(Keys.Space, false, true, false, false, ad1);
            sourceCodeBox.KeyboardActions.Add(ka1);

            //Save on CTRL+S
            ActionDelegate ad2 = new ActionDelegate(this.SaveCurrentCode);
            KeyboardAction ka2 = new KeyboardAction(Keys.S, false, true, false, false, ad2);
            sourceCodeBox.KeyboardActions.Add(ka2);
            
            //Add * to tab text when file becomes dirty
            sourceCodeBox.Document.Tag = sourceCodeBox;
            sourceCodeBox.Document.ModifiedChanged += Document_ModifiedChanged;

        }

        public Alsing.Windows.Forms.SyntaxBoxControl SourceCodeBox
        {
            get {

                SyntaxBoxControl tempsbc = null;
                Control c = this.sourceTabs.SelectedTab.Controls[0];
                if (!(c is SyntaxBoxControl))
                {
                    foreach (Control cont in this.sourceTabs.SelectedTab.Controls)
                    {
                        if (cont is SyntaxBoxControl)
                        {
                            tempsbc = (SyntaxBoxControl)cont;
                        }
                    }
                }
                else
                {
                    tempsbc = (SyntaxBoxControl)c;
                }
                return tempsbc;
            }
        }

        private void ShowAutoList()
        {
            var sbc = SourceCodeBox;
            sbc.AutoListClear();
            sbc.AutoListAutoSelect = false;
            sbc.AutoListBeginLoad();
            
//            foreach (string key in myContext.GetContext.Keys)
//            {
//                sourceCodeBox.AutoListAdd(key, 1);
//            }

            FillTheAutoList(sbc.Caret.CurrentRow.Text, sbc);

            sbc.AutoListEndLoad();

            sbc.AutoListPosition = sbc.Caret.Position;
            
        }

        private void FillTheAutoList(string text, SyntaxBoxControl sbc)
        {
            if (text.Contains(" "))
            {
                text = text.Substring(text.LastIndexOf(' '));
            }
            if (text.Contains("("))
            {
                text = text.Substring(text.LastIndexOf('(') + 1);                
            }
            //if (!text.Contains("."))
            {
                text = text.Trim().TrimEnd('.');
                //if (myContext.GetContext.Keys.Contains(text))
                if (myContext.Scope.ContainsVariable(text))
                {                    
                    object variable = myContext.Scope.GetVariable(text);
                    IList<string> properties = SPCoderUtils.GetProperties(variable);
                    foreach (string property in properties)
                    {
                        sbc.AutoListAdd(property, 1);
                    }

                    IList<string> methods = SPCoderUtils.GetMethods(variable);
                    foreach (string method in methods)
                    {
                        sbc.AutoListAdd(method, method.Substring(0, method.IndexOf(')') + 1), 2);
                        //sourceCodeBox.AutoListAdd(method, 2);
                    }
                    sbc.AutoListVisible = true;
                }
                else
                {
                    foreach (var variable in myContext.GetContext.Keys)
                    {
                        sbc.AutoListAdd(variable, 1);
                    }
                    sbc.AutoListVisible = true;
                }
            }
//            string[] vars = text.Split('.');
//            foreach (string variable in vars)
//            {
//                
//            }
        }

        private void ExecuteAutorunScripts()
        {
            try
            {
                List<string> scripts = AutorunScriptUtils.GetAutorunScriptSources();
                foreach (string script in scripts)
                {
                    try
                    {
                        ExecuteScript(script);
                    }
                    catch (Exception ex)
                    {
                        //LogException(ex);
                        AppendToLog(ex.Message); 
                    }
                }
            }
            catch (Exception ex)
            {
                LogException(ex);                
            }
        }

        private void Main_FormClosing(object sender, FormClosingEventArgs e)
        {            
            foreach (TreeNode treeNode in tvSp.Nodes)
            {
                DisposeNode(treeNode);
            }

            foreach (BaseNode node in Nodes)
            {
                DisposeBaseNodes(node);
            }
        }

        private void lbContext_KeyPress(object sender, KeyPressEventArgs e)
        {
            //char c = (Char) Keys.Delete;
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                object[] items = new object[lbContext.SelectedItems.Count];
                int i = 0;
                foreach (object item in lbContext.SelectedItems)
                {
                    items[i++] = item;
                    
                }
                foreach (object item in items)
                {
                    myContext.RemoveItem((ContextItem)item);
                    lbContext.Items.Remove(item);                     
                }                
            }
            catch (Exception ex)
            {
                LogException(ex);
            }
        }

        private void tsDescribe_Click(object sender, EventArgs e)
        {
            if (lbContext.SelectedItem != null)
            {
                ContextItem item = (ContextItem)lbContext.SelectedItem;                
                DescriberForm describerForm = new DescriberForm(item);
                describerForm.Show(this);
            }       
        }

        private void virToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
        }

        private void contextMenuStrip1_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {

        }

        private void tEstToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //pgEditor
            if (lbContext.SelectedItem != null)
            {
                ContextItem item = (ContextItem)lbContext.SelectedItem;
                PgEditor.SelectedObject = item.Data;
                //Show the Properties tab:
                outputTabs.SelectedTab = tabPage2;
            }  
        }

        private void toolStripButton6_Click(object sender, EventArgs e)
        {
            GenerateNewSourceTab("New Script *", "", null);
        }

        /// <summary>
        /// Creates the new source tab.
        /// </summary>
        /// <param name="title">Title of the window</param>
        /// <param name="source">Source code</param>
        /// <param name="fullFileName">Full file path</param>
        public void GenerateNewSourceTab(string title, string source, string fullFileName)
        {
            SyntaxBoxControl sbc = new SyntaxBoxControl();
            var loader = new SyntaxDefinitionLoader();
            string syntaxXml = SPCoderUtils.LoadStringFromResource("SPCoder.Resources.Python.syn");
            SyntaxDefinition syntax = loader.LoadXML(syntaxXml);
            sbc.Document.Parser.Init(syntax);
            sbc.Anchor = AnchorStyles.Left | AnchorStyles.Top;
            sbc.Dock = DockStyle.Fill;

            sbc.Document.Text = source;
            sbc.Tag = fullFileName;
            //Execute on F5
            ActionDelegate ad = new ActionDelegate(this.ExecuteSelection);
            KeyboardAction ka = new KeyboardAction(Keys.F5, false, false, false, false, ad);
            sbc.KeyboardActions.Add(ka);

            //AutoList on CTRL+SPACE
            ActionDelegate ad1 = new ActionDelegate(this.ShowAutoList);
            KeyboardAction ka1 = new KeyboardAction(Keys.Space, false, true, false, false, ad1);
            sbc.KeyboardActions.Add(ka1);

            //Save on CTRL+S
            ActionDelegate ad2 = new ActionDelegate(this.SaveCurrentCode);
            KeyboardAction ka2 = new KeyboardAction(Keys.S, false, true, false, false, ad2);
            sbc.KeyboardActions.Add(ka2);

            //Add * to tab text when file becomes dirty
            sbc.Document.Tag = sbc;
            sbc.Document.ModifiedChanged +=Document_ModifiedChanged;
            
            

            TabPage newTab = new TabPage(title);
            newTab.Controls.Add(sbc);
            this.sourceTabs.TabPages.Add(newTab);
            this.sourceTabs.SelectedTab = newTab;
        }

        void Document_ModifiedChanged(object sender, EventArgs e)
        {
            if (sender is SyntaxDocument)
            { 
                SyntaxDocument doc = (SyntaxDocument)sender;                
                SyntaxBoxControl sbc = doc.Tag as SyntaxBoxControl;
                if (sbc != null)
                { 
                    TabPage tab = (TabPage)sbc.Parent;
                    if (!tab.Text.EndsWith("*"))
                    {
                        tab.Text = tab.Text + "*";
                    }
                }
            }            
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            OpenFileDialog fd = new OpenFileDialog();
            fd.FileOk += openFileDialog1_FileOk;
            fd.ShowDialog(this);            
        }

        private void openFileDialog1_FileOk(object sender, System.ComponentModel.CancelEventArgs e)
        {
            OpenFileDialog fd = (OpenFileDialog)sender;
            Stream s = fd.OpenFile();
            StreamReader tr = new StreamReader(s);
            string source = tr.ReadToEnd();
            tr.Close();
            string title = fd.SafeFileName;
            string fullFileName = fd.FileName;

            GenerateNewSourceTab(title, source, fullFileName);
        }

        private void renameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //Rename the object in the context
            try
            {                
                object item = lbContext.SelectedItem;                
                ContextItemRenamer renamer = new ContextItemRenamer {Item = item};
                renamer.Rename += DoRenameContextItem;
                renamer.ShowDialog(this);                
            }
            catch (Exception ex)
            {
                LogException(ex);
            }
        }

        private void DoRenameContextItem(object item, string newName)
        {
            ContextItem myItem = (ContextItem) item;
            int ind = lbContext.Items.IndexOf(myItem);
            string oldName = myItem.Name;
                
            if (myContext.Scope.ContainsVariable(newName))
            {
                string err = string.Format("The variable '{0}' already exists in context", newName);
                AppendToLog(err);
                throw new Exception(err);
            }

            myContext.RenameItem(myItem, newName);
            lbContext.Items.Remove(myItem);
            if (ind != -1)
            {
                lbContext.Items.Insert(ind, myItem);
            }
            else
            {
                lbContext.Items.Add(myItem);
            }

            AppendToLog(string.Format("Object '{0}' renamed to '{1}'", oldName, newName));
        }

        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            //Save   
            SaveCurrentCode(true);
        }

        private void SaveCurrentCode()
        {
            SaveCurrentCode(true);
        }

        private bool SaveCurrentCode(bool forceOverwrite)
        {
            //Save a file
            //If it had already been saved, just overwrite the file
            //if ()
            bool result = false;
            SyntaxBoxControl tempsbc = SourceCodeBox;
            if (tempsbc == null)
            {
                throw new Exception("Cannot find control box control!");
            }
            string text = tempsbc.Document.Text;
            bool written = false;
            if (forceOverwrite)
            {
                if (tempsbc.Tag != null && !string.IsNullOrEmpty(tempsbc.Tag.ToString()))
                {
                    string tempFileName = tempsbc.Tag.ToString();
                    if (System.IO.File.Exists(tempFileName))
                    {
                        File.WriteAllText(tempFileName, text, Encoding.UTF8);
                        AppendToLog(string.Format("File '{0}' has been saved.", tempFileName));
                        written = true;
                        TabPage tab = (TabPage)tempsbc.Parent;
                        tab.Text = Path.GetFileName(tempFileName);
                        result = true;
                    }
                }
                else
                {
                    forceOverwrite = false;
                }
            }
            
            if (!forceOverwrite)
            {
                if (!written)
                {
                    //else, open the dialog and save it
                    SaveFileDialog saveFileDialog = new SaveFileDialog();
                    saveFileDialog.Title = "Save script";
                    saveFileDialog.DefaultExt = "py";
                    saveFileDialog.InitialDirectory = ConfigUtils.FullDirectoryPath;
                    saveFileDialog.Filter = "IronPython files|*.py|All files|*.*";

                    saveFileDialog.FileOk += new System.ComponentModel.CancelEventHandler(saveFileDialog_FileOk);
                    saveFileDialog.ShowDialog(this);
                    if (string.IsNullOrEmpty(saveFileDialog.FileName))
                    {                        
                        return false;
                    }
                    
                    //if (!Uri.IsWellFormedUriString(saveFileDialog.FileName, UriKind.Absolute))
                    //{
                    //    MessageBox.Show(this, "Path is not valid", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    //    return;
                    //}
                    File.WriteAllText(saveFileDialog.FileName, text, Encoding.UTF8);
                    written = true;
                    TabPage tab = (TabPage)tempsbc.Parent;
                    tab.Text = Path.GetFileName(saveFileDialog.FileName);
                    tempsbc.Tag = saveFileDialog.FileName;
                    AppendToLog(string.Format("File '{0}' has been saved.", saveFileDialog.FileName));
                    result = true;
                }
            }
            return result;
        }

        private void saveFileDialog_FileOk(object sender, CancelEventArgs e)
        {
            //SaveFileDialog dialog = (SaveFileDialog) sender;
            

        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            GenerateNewSourceTab("New Script *", "", null);
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog fd = new OpenFileDialog();
            fd.FileOk += openFileDialog1_FileOk;
            fd.ShowDialog(this);      
        }

        private void btnSaveAs_Click(object sender, EventArgs e)
        {
            SaveCurrentCode(false);
        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TabPage tab = sourceTabs.SelectedTab;
            if (tab.Text.EndsWith("*"))
            {
                DialogResult dialog = MessageBox.Show("Do you want to save script before closing?","Save the script",MessageBoxButtons.YesNoCancel,MessageBoxIcon.Question);
                if (dialog == DialogResult.Yes)
                {
                    SaveCurrentCode(false);
                    sourceTabs.TabPages.Remove(tab);
                }
                else if (dialog == DialogResult.No)
                {
                    sourceTabs.TabPages.Remove(tab);
                }
                //in case of Cancel just continue.
            }
            else
            {
                sourceTabs.TabPages.Remove(tab);
            }
        }

        private void sourceTabs_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (sourceTabs.TabPages.Count > 1)
                {
                    this.cmsTabs.Show(this.sourceTabs, e.Location);
                }
            }
        }

        private void btnSaveAsAutoRunScript_Click(object sender, EventArgs e)
        {
            SaveAsAutorunScript();
        }

        private void SaveAsAutorunScript()
        {
            //First check if this script has been saved.
            bool result = SaveCurrentCode(true);

            if (!result)
            {
                return;
            }
            SyntaxBoxControl tempsbc = SourceCodeBox;
            if (tempsbc == null)
            {
                throw new Exception("Cannot find control box control!");
            }
            string tempFileName = tempsbc.Tag.ToString();

            //After saving the script add it as autorun script at the last position, and then open the autorun scripts window
            var currentConfig = AutorunScriptUtils.GetAutorunConfig();
            int order = (currentConfig.AutoRunScripts == null) ? 1 : currentConfig.AutoRunScripts.Count + 1;
            var script = new AutorunScriptConfigItem();
            script.Order = order;
            script.Path = tempFileName;
            script.Title = Path.GetFileName(tempFileName);

            currentConfig.AutoRunScripts.Add(script);
            AutorunScriptUtils.SaveConfig(currentConfig);
            rtLog.Text += "[" + DateTime.Now.ToLongTimeString() + "]: Added new autorun script\n";

            AutoRunScriptsForm arsForm = new AutoRunScriptsForm();
            arsForm.ShowDialog(this);
        }

        private void propertiesToolStripMenuItem2_Click(object sender, EventArgs e)
        {

        }

        private void propertiesToolStripMenuItem1_Click(object sender, EventArgs e)
        {

        }

        private void cms2TreeView_Opening(object sender, CancelEventArgs e)
        {

        }

        private void codeWindowToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void toolStripRefresh_Click(object sender, EventArgs e)
        {
            //Refresh
            BaseNode node = this.tvSp.SelectedNode.Tag as BaseNode;
        }

        private void tvSp_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            //if (e.Button == MouseButtons.Right)
            //{

            //    this.tvSp.SelectedNode = e.Node;
            //    this.cms2TreeView.Show(this.tvSp, e.Location);
            //}
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveCurrentCode(true);
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveCurrentCode(false);
        }

        private void saveAsAutorunToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveAsAutorunScript();
        }

        private void autorunToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AutoRunScriptsForm arsForm = new AutoRunScriptsForm();
            arsForm.ShowDialog(this);
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox box = new AboutBox();
            box.ShowDialog(this);
        }
    }
}